﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;
using Google.GData.Client;
using Google.GData.Contacts;

namespace GravatarContacts
{
    class GravatarImporter
    {
        private Thread _workerThread;
        
        private String _referenceImagePath;
        private String _tempFilePath;
        
        private String _username;
        private String _password;
        
        private int _gravatarSize = 2;
        private ContactsFeed _contactsFeed;
        private WebClient _httpClient;
        private ContactsService _service;

        int _totalContactsWithPhotosCount;
        int _gravatarsCount;

        public delegate void HandleFinish(int totalContactsCount, int totalContactsWithPhotosCount, int gravatarsCount);
        public delegate void HandleEmail(string email);
        public delegate void HandleContactsCount(int count);
        public event HandleContactsCount ContactsLoaded;
        public event HandleEmail AddedEmail;
        public event HandleEmail FoundGravatar;
        public event HandleFinish Finished;

        public GravatarImporter()
        {
            _referenceImagePath = @"c:\users\me\compare.jpg";
            _tempFilePath = @"c:\users\me\temp.jpg";
            _httpClient = new WebClient();
        }

        public void Import(String username, string password)
        {
            _username = username;
            _password = password;

            _totalContactsWithPhotosCount = 0;
            _gravatarsCount = 0;

            LoadContacts();
            OnContactsLoaded(_contactsFeed.Entries.Count);
            LoadReferenceImage();

            System.Diagnostics.Debug.Assert(_contactsFeed != null);

            _workerThread  = new Thread(new ThreadStart(this.IterateContacts));
            _workerThread.IsBackground = true;
            _workerThread.Start();            
        }

        public void Abort()
        {
            _workerThread.Abort();
        }

        protected void IterateContacts()
        {
            foreach (ContactEntry entry in _contactsFeed.Entries)
            {
                CheckContact(entry);
            }
            if (Finished != null)
            {
                Finished(_contactsFeed.Entries.Count, _totalContactsWithPhotosCount, _gravatarsCount);
            }
        }

        protected void CheckContact(ContactEntry entry)
        {
            String entryEmail = entry.PrimaryEmail.Address.ToString();
            OnAddedEmail(entryEmail);
            if (entry.PhotoUri == null)
            {
                if (HasGravatar(entryEmail))
                {
                    if (FoundGravatar != null)
                    {
                        String gravatar = Gravatar.Gravatar.GetGravatarUrl(entryEmail, 512);
                        //_httpClient.DownloadFile(gravatar, _tempFilePath);
                        var stream = _httpClient.OpenRead(gravatar);
                        _service.Update(entry.PhotoEditUri, stream, "image/jpeg", "");

                        FoundGravatar(entryEmail);
                        _gravatarsCount++;
                    }
                }
            }
            else
            {
                _totalContactsWithPhotosCount++;
            }
        }

        protected bool HasGravatar(String email)
        {
            String gravatar = Gravatar.Gravatar.GetGravatarUrl(
                email, _gravatarSize);

            _httpClient.DownloadFile(gravatar, _tempFilePath);

            if (!FileUtil.FileCompare(_tempFilePath, _referenceImagePath))
            {
                return true;
            }

            return false;
        }

        protected void LoadContacts()
        {
            string contactsURI = "http://www.google.com/m8/feeds/contacts/default/full";

            ContactsQuery query = new ContactsQuery();
            _service = new ContactsService("GravatarContacts");
                        
            _service.setUserCredentials(_username, _password);
            
            query.Uri = new Uri(contactsURI);
            query.ExtraParameters = "max-results=5000";

            _contactsFeed = _service.Query(query) as ContactsFeed; 
            
        }

        protected void LoadReferenceImage()
        {
            String gravatarUrl =
                "http://gravatar.com/avatar/d5f7228c95f5ad7f399cc371346b3dd5?s=" + _gravatarSize;
            _httpClient.DownloadFile(gravatarUrl, _referenceImagePath);
        }

        protected void OnAddedEmail(String email)
        {
            if (AddedEmail != null)
            {
                AddedEmail(email);
            }
        }
        protected void OnContactsLoaded(int count)
        {
            if (ContactsLoaded != null)
            {
                ContactsLoaded(count);
            }
        }
    }
}
